
// 扩展验证规则
(function () {
    // 验证Combo和ComboBox的值，根据选中值来验证，而非文本框的值
    $.extend($.fn.validatebox.defaults.rules, {

        // 适用于非Grid表单
        // 参数：ElementFullID
        selectionRequired: {
            validator: function (value, param) {
                if (!param || param.length <= 0) {
                    return false;
                }

                var control = $('#' + param[0]);
                if (!control || control.length <= 0) {
                    return false;
                }

                var selectValue = parseInt(control.combobox('getValue'));
                if (!selectValue || selectValue <= 0) {
                    return false;
                }

                if ($(control[0].parentNode).find('.combotree-f').length > 0) {
                    var findNode = control.combotree("tree").tree('find', selectValue);
                    if (findNode && findNode.text == control.combobox('getText')) {
                        return true;
                    }
                }
                else {
                    var data = control.combobox('getData');
                    if (!data || !data.getSelectionByValue) {
                        return false;
                    }

                    var selectItem = data.getSelectionByValue(selectValue);
                    if (selectItem && selectItem.text == control.combobox('getText')) {
                        return true;
                    }
                }

                return false;
            },
            message: '请选择'
        },

        // 参数：MinNumberValue,MaxNumberValue
        numberRange: {
            validator: function (value, param) {
                if (!param || param.length <= 1) {
                    return false;
                }

                if ((!amCommon.notEmpty(param[0]) || param[0] == '～' || value >= param[0]) && (!amCommon.notEmpty(param[1]) || param[1] == '～' || value <= param[1])) {
                    return true;
                }

                return false;
            },
            message: '数值在{0}到{1}之间'
        },

        // 参数：CompareFieldName,CompareFieldDisplayName
        dateGreaterOrEqual: {
            validator: function (value, param) {
                if (!param || param.length <= 1) {
                    return false;
                }

                var compareValue = eval('viewModel.form.' + param[0] + '()');
                if (!amCommon.notEmpty(value) || !amCommon.notEmpty(compareValue)) {
                    return true;
                }
                else {
                    eval('viewModel.form.' + param[0] + '("' + compareValue + '")');
                    if (Date.prototype.compare(value, compareValue) >= 0) {
                        return true;
                    }
                }

                return false;
            },
            message: '值必须大于等于【{1}】栏位'
        },

        // 参数：CompareFieldName,CompareFieldDisplayName
        dateLessOrEqual: {
            validator: function (value, param) {
                if (!param || param.length <= 1) {
                    return false;
                }

                var compareValue = eval('viewModel.form.' + param[0] + '()');
                if (!amCommon.notEmpty(value) || !amCommon.notEmpty(compareValue)) {
                    return true;
                }
                else {
                    eval('viewModel.form.' + param[0] + '("' + compareValue + '")');
                    if (Date.prototype.compare(value, compareValue) <= 0) {
                        return true;
                    }
                }

                return false;
            },
            message: '值必须小于等于【{1}】栏位'
        },

        dateGreaterToday: {
            validator: function (value, param) {
                var today = new Date();
                var formToday = today.getFullYear().toString() + "-" + (today.getMonth() + 1).toString() + "-" + today.getDate().toString();
                if (Date.prototype.compare(value, formToday) >= 0) {
                    return true;
                }

                return false;
            },
            message: '时间必须大于等于今天'
        },

       dateLessToday: {
            validator: function (value, param) {
                var today = new Date();
                var formToday = today.getFullYear().toString() + "-" + (today.getMonth() + 1).toString() + "-" + today.getDate().toString();
                if (Date.prototype.compare(value, formToday) <= 0) {
                    return true;
                }

                return false;
            },
            message: '工时申报时间必须小于或等于当前日期'
       },

        serialNumber: {
            validator: function (value, param) {
                return /^[\w|\-|\.]+$/.test(value);
            },
            message: '请输入字母、数字、下划线、中横线或小数点'
        },

        wordNumber: {
            validator: function (value, param) {
                return /^[\w]+$/.test(value);
            },
            message: '请输入字母、数字或下划线'
        },

        startWordNumber: {
            validator: function (value, param) {
                return /^[A-Za-z]+[A-Za-z0-9]*$/.test(value);
            },
            message: '请输入字母或数字，且首位为字母'
        },

        summaryQueryString: {
            validator: function (value, param) {
                return /^[/|\*|\-|\+|\w| |\[|\]|,|\n|\t|\r|=|\(|\)|\.|'|%|@]*SELECT[ |\n|\t|\r]+(\[ID\]|ID)[ |,|\n|\t|\r|=][/|\*|\-|\+|\w| |\[|\]|,|\n|\t|\r|=|\(|\)|\.|'|%|@|<|>]*$/i.test(value);
            },
            message: '请输入正确的查询SQL！且查询的第一个字段必须是主键ID'
        },

        nameMatching: {
            validator: function (value, param) {
                return /(^(\S)*)$/.test(value);
            },
            message: '为方便查看，请不要输入空白字符！'
        },

        ipRange: {
            validator: function (value, param) {
                return /^(((\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){3}(\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))))((,(((\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){3}(\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))))*|(-(((\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5])))\.){3}(\d|([1-9]\d)|(1\d\d)|(2([0-4]\d|5[0-5]))))(?!-))*)*$/.test(value);
            },
            message: '请输入正确的IP范围：多个独立IP之间用英文逗号分隔；也可以输入IP范围中间用小横杠分隔'
        },

        urlJudege: {
            validator: function (value, param) {
                return /^((http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)|((\/\w+)+((\?)(\w+\=\w+))?(&(\w+\=\w+))*)$/.test(value);
            },
            message: 'URL格式不正确，请输入正确的格式！'
        },

        boolExpression: {
            validator: function (value, param) {
                return /^\[\w*\](==|!=|>|>=|<|<=).*$/.test(value);
            },
            message: '值必须是布尔表达式，并且左侧是括起来的字段名，比如[Days]>3'
        },

        // 适用于非Grid表单
        // 参数：CurrentElementFullID,DependFieldName,DependFieldDisplayName
        dependRequired: {
            validator: function (value, param) {
                if (!param || param.length <= 2 || !amCommon.notEmpty(param[0]) || !amCommon.notEmpty(param[1])) {
                    return false;
                }

                var dependItem = param[1];
                var dependValue = eval('viewModel.form.' + dependItem + '()');

                var currentElement = $('#' + param[0]);
                if (amCommon.notEmpty(dependValue)) {
                    if (currentElement.length > 0) {
                        currentElement[0].exDependItemValue = dependValue;
                    }
                    return true;
                }
                else {
                    if (currentElement.length > 0) {
                        currentElement[0].exDependItemValue = null;
                    }
                    return false;
                }

                return amCommon.notEmpty(dependValue);
            },
            message: '请先填写【{2}】栏位'
        }
    });

})(jQuery);

// 定义ko对于easyui的控件值绑定器
ko.bindingHandlers.Value = {
    init: function (element, valueAccessor, allBindingsAccessor) {

        var options = null;
        var jqElement = $(element);
        var typeString = jqElement.attr('type');
        var classString = jqElement.attr("class");
        if (typeString && typeString == "checkbox") {
            // mark 尚未获取options
            jqElement.click(function () {
                var newValue = $(element).prop("checked");
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue);
                }
            });
        } else if (classString.indexOf('easyui-validatebox') >= 0) {
            options = jqElement.validatebox('options');
            jqElement.on('change', function (e) {
                var newValue = $(element).val();
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue);
                }
            });
        } else if (classString.indexOf('numberbox-f') >= 0) {
            options = jqElement.textbox('options');
            options.onChange = function (newValue, oldValue) {
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue, oldValue);
                }
            };
        } else if (classString.indexOf('spinner-f') >= 0) {
            options = jqElement.textbox('options');
            options.onChange = function (newValue, oldValue) {
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue, oldValue);
                }
            };
        } else if (classString.indexOf('datebox-f') >= 0) {
            var comboClear = new comboClearFunction(element);
            comboClear.addClearButton();

            options = jqElement.combo('options');
            options.onChange = function (newValue, oldValue) {
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        if (newValue == undefined
                            || newValue == "") {
                            value("");
                        }
                        else {
                            value((new Date(newValue)).format("yyyy-MM-dd"));
                        }
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue, oldValue);
                }

                comboClear.showClearButton(newValue);
            };
        } else if (classString.indexOf('combobox-f') >= 0) {
            var comboClear = new comboClearFunction(element);
            comboClear.addClearButton();

            options = jqElement.combo('options');
            options.onChange = function (newValue, oldValue) {
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);

                        // 解决多选框之后的文本框无法保存值的问题
                        if ($(element).combobox("options").multiple == true
                            && !($(element).combo('panel').is(":hidden"))) {
                            $(element).combo('hidePanel');
                            $(element).combo('showPanel');
                        }
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue, oldValue);
                }

                comboClear.showClearButton(newValue);
            };
        } else if (classString.indexOf('combotree-f') >= 0) {
            var comboDisable = new comboDisableFunction();
            var comboClear = new comboClearFunction(element);
            comboClear.addClearButton();

            options = jqElement.combo('options');
            options.onChange = function (newValue, oldValue) {
                if (valueAccessor) {
                    var value = valueAccessor();
                    if (value) {
                        value(newValue);

                        // 解决多选框之后的文本框无法保存值的问题
                        if ($(element).combotree("options").multiple == true
                            && !($(element).combo('panel').is(":hidden"))) {
                            $(element).combo('hidePanel');
                            $(element).combo('showPanel');
                        }
                    }
                }

                if (element.exEventChange) {
                    element.exEventChange(newValue, oldValue);
                }

                comboClear.showClearButton(newValue);
            };

            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);

                // 解决下拉多选框不能显示初始值问题
                if ($(element).combotree("options").multiple == true) {
                    var control = $(element).combotree("tree");
                    control.tree('options').onLoadSuccess = function (node, data) {
                        for (i = 0; i < val.length ; i++) {
                            var findNode = control.tree('find', val[i]);
                            if (findNode) {
                                control.tree('check', findNode.target);
                                if (findNode.isParent == 'true') {
                                    control.tree('expandAll', findNode.target);
                                }
                            }
                        }

                        comboDisable.disable(element, $(element).combo("getText"));
                    };
                }
                else {
                    var control = $(element).combotree("tree");
                    control.tree('options').onLoadSuccess = function (node, data) {

                        $(element).combotree('setValue', val);

                        var controlText = val;
                        var findNode = control.tree('find', val);
                        if (findNode) {
                            control.tree('select', findNode.target);
                            controlText = findNode.text;
                        }
                        comboDisable.disable(element, controlText);
                    };
                }

                $(element).combo('textbox').keyup(function (event) {
                    if (!window.typeKeyIsAction(event.keyCode)) {

                        // 用户手动删除了所有文本时，则把选中值清空
                        comboClear.showClearButton();
                        var newQueryText = $(element).combo("getText");
                        if (newQueryText == undefined
                            || newQueryText == null
                            || newQueryText.toString().length <= 0) {

                            comboClear.doClearValue();
                        }
                    }
                });
            }
        }
    },
    update: function (element, valueAccessor) {
        var typeString = $(element).attr('type');
        var classString = $(element).attr("class");
        if (typeString && typeString == "checkbox") {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);
                var checked = false;
                if (val == true || val == "true" || val == "yes"
                    || val == "1" || val == "是" || val == "√") {
                    checked = true;
                }
                $(element).prop("checked", checked);

                var options = $(element).attr("data-options");
                if (options != null) {
                    var regex = /disabled:([^,]+)(?:$|,)/;
                    var disabledExpression = options.match(regex);
                    if (disabledExpression != null && disabledExpression.length > 1) {
                        var disabledValue = eval('(' + disabledExpression[1].toString() + ')');
                        if (disabledValue == true) {
                            $(element).prop("disabled", true);
                        }
                    }
                }
            }
        } else if (classString.indexOf('easyui-validatebox') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                $(element).val(ko.utils.unwrapObservable(value));
            }

            // 解决“设置默认值后文本框还是提示必填”的问题
            $(element).validatebox('validate');

            var textboxDisable = new textboxDisableFunction();
            textboxDisable.disable(element, $(element).val());
        } else if (classString.indexOf('numberbox-f') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);
                $(element).numberbox('setValue', val);

                var textboxDisable = new textboxDisableFunction();
                textboxDisable.disable(element, val);
            }

            // 解决“设置默认值后文本框还是提示必填”的问题
            $(element).numberbox('validate');
        } else if (classString.indexOf('spinner-f') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);
                $(element).numberbox('setValue', val);

                var textboxDisable = new textboxDisableFunction();
                textboxDisable.disable(element, val);
            }

            // 解决“设置默认值后文本框还是提示必填”的问题
            $(element).numberbox('validate');
        } else if (classString.indexOf('datebox-f') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);
                $(element).datebox('setValue', val);

                // 解决通过viewModel.form.XXDate("2014-01-01")无法保存的问题
                if (value() == "NaN-aN-aN") {
                    value(val);
                }

                var comboDisable = new comboDisableFunction();
                comboDisable.disable(element, val);
            }
        } else if (classString.indexOf('combobox-f') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);

                if ($(element).combobox("options").multiple == true) {
                    $(element).combobox('setValues', val);
                }
                else {
                    $(element).combobox('setValue', val);
                }

                if ($(element).combobox("options").disabled == true) {
                    var comboDisable = new comboDisableFunction();
                    comboDisable.disable(element, $(element).combobox("getText"));
                }
            }
        } else if (classString.indexOf('combotree-f') >= 0) {
            if (valueAccessor) {
                var value = valueAccessor();
                var val = ko.utils.unwrapObservable(value);

                if ($(element).combotree("options").multiple == true) {
                    $(element).combotree('setValues', val);
                }
                else {
                    $(element).combotree('setValue', val);
                }
            }
        }
    }
};

// 用户控件绑定器
ko.bindingHandlers.textButtonValue = {
    setValue: function (value, selectedValues, multi) {
        if (value) {
            if (!amCommon.notEmpty(selectedValues)) {
                value("");
            }
            else {
                if (multi == true) {
                    value(selectedValues);
                }
                else {
                    value(selectedValues[0]);
                }
            }
        }
    },
    init: function (element, valueAccessor, allBindingsAccessor) {

        var jqElement = $(element);
        var options = jqElement.combobox('options');
        var comboClear = new comboClearFunction(element);
        comboClear.addClearButton();

        if (valueAccessor) {
            var multi = options.multiple;
            var value = valueAccessor();

            var comboTextButton = new comboTextButtonFunction(element);
            comboTextButton.addTextButton();
            comboTextButton.setComboValue = function (selectedValues) {
                ko.bindingHandlers.textButtonValue.setValue(value, selectedValues, multi);
            };

            var comboAutoComplete = new comboAutoCompleteFunction(element, comboClear);
            comboAutoComplete.userAutoComplete();
            comboAutoComplete.onAutoComplete = function (selectedValues) {
                ko.bindingHandlers.textButtonValue.setValue(value, selectedValues, multi);
            };
        }

        function selectChange() {
            var newValue = jqElement.combobox('getValues');
            if (valueAccessor) {
                var value = valueAccessor();
                var multi = jqElement.combobox("options").multiple;
                ko.bindingHandlers.textButtonValue.setValue(value, newValue, multi);
            }

            if (element.exEventChange) {
                element.exEventChange(newValue);
            }

            comboClear.showClearButton(newValue);
        };

        options.onSelect = selectChange;

        jqElement.combo('options').onChange = function (newValue, oldValue) {
            comboClear.showClearButton(newValue);

            if (!amCommon.notEmpty(newValue)) {
                selectChange();
            }
        };
    },
    update: function (element, valueAccessor) {
        if (valueAccessor) {
            var value = valueAccessor();
            var val = ko.utils.unwrapObservable(value);

            if ($(element).combobox("options").multiple == true) {
                $(element).combobox('setValues', val);
            }
            else {
                if (amCommon.notEmpty(val)) {
                    $(element).combobox('select', val);
                }
                $(element).combobox('setValue', val);
            }
            (new comboClearFunction(element)).showClearButton(val);

            if ($(element).combobox("options").disabled == true) {
                var comboDisable = new comboDisableFunction();
                comboDisable.disable(element, $(element).combo("getText"));
            }
        }
    }
};

// 业务数据选择控件绑定器
ko.bindingHandlers.popupSelectValue = {
    setValue: function (value, selectedValues, multi) {
        if (value) {
            if (!amCommon.notEmpty(selectedValues)) {
                value("");
            }
            else {
                if (multi == true) {
                    value(selectedValues);
                }
                else {
                    value(selectedValues[0]);
                }
            }
        }
    },
    init: function (element, valueAccessor, allBindingsAccessor) {
        var comboClear = new comboClearFunction(element);
        comboClear.addClearButton();

        var jqElement = $(element);
        var options = jqElement.combo('options');
        if (valueAccessor && options) {
            var multi = jqElement.combobox("options").multiple;
            var value = valueAccessor();

            if ((options.foreignTableID > 0 || options.foreignTableUrl)
                && options.foreignTableDisplayName
                && options.foreignKeyItemName
                && options.foreignTextItemName) {

                var comboPopupSelect = new comboPopupSelectFunction(element,
                    options.foreignTableID, options.foreignTableDisplayName, options.foreignTextItemName);
                comboPopupSelect.addPopupSelect();
                comboPopupSelect.iExtraFilter = options.iExtraFilter;
                comboPopupSelect.setComboValue = function (selectedValues) {
                    ko.bindingHandlers.popupSelectValue.setValue(value, selectedValues, multi);
                };

                if (options.editable == true) {
                    var comboAutoComplete = new comboAutoCompleteFunction(element, comboClear);
                    if (options.foreignViewID > 0) {
                        comboAutoComplete.summaryAutoComplete(options.foreignViewID, options.foreignViewTextItemName);
                    }
                    else {
                        comboAutoComplete.foreignKeyAutoComplete(options.foreignTableID, options.foreignTextItemName);
                    }
                    comboAutoComplete.onAutoComplete = function (selectedValues) {
                        ko.bindingHandlers.popupSelectValue.setValue(value, selectedValues, multi);
                    };
                }
            }
        }

        function selectChange() {
            var newValue = $(element).combobox('getValues');
            if (valueAccessor) {
                var value = valueAccessor();
                var multi = $(element).combobox("options").multiple;
                ko.bindingHandlers.popupSelectValue.setValue(value, newValue, multi);
            }

            if (element.exEventChange) {
                element.exEventChange(newValue);
            }

            comboClear.showClearButton(newValue);
        };

        jqElement.combobox('options').onSelect = selectChange;

        options.onChange = function (newValue, oldValue) {
            comboClear.showClearButton(newValue);

            if (!amCommon.notEmpty(newValue)) {
                selectChange();
            }
        };
    },
    update: function (element, valueAccessor) {
        if (valueAccessor) {
            var value = valueAccessor();
            var val = ko.utils.unwrapObservable(value);

            if (amCommon.isArray(val)) {
                $(element).combobox('setValues', val);
            }
            else {
                if (amCommon.notEmpty(val)) {
                    $(element).combobox('select', val);
                }
                $(element).combobox('setValue', val);
            }

            (new comboClearFunction(element)).showClearButton(val);

            if ($(element).combobox("options").disabled == true) {
                var comboDisable = new comboDisableFunction();
                comboDisable.disable(element, $(element).combo("getText"));
            }
        }
    }
};

// 图片控件绑定器
ko.bindingHandlers.picturePanelValue = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        if (valueAccessor
            && allBindingsAccessor) {
            var value = valueAccessor();
            var allBindings = allBindingsAccessor();

            if (value) {
                value(allBindings.pictureBatchID);
            }
        }
    }
};

// 附件控件绑定器
ko.bindingHandlers.filePanelValue = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        if (valueAccessor
            && allBindingsAccessor) {
            var value = valueAccessor();
            var allBindings = allBindingsAccessor();

            if (value) {
                value(allBindings.fileBatchID);
            }
        }
    }
};

// 序列号控件绑定器
ko.bindingHandlers.serialNumberValue = {
    init: function (element, valueAccessor, allBindingsAccessor) {

        var jqElement = $(element);
        var options = jqElement.combo('options');
        var disabled = options.exDisabled;
        var comboClear = new comboClearFunction(element);
        if (disabled != true) {
            comboClear.addClearButton();
        }

        var itemName = jqElement.attr('id');
        comboSerialNumberFunction.initControl(element, itemName, disabled);

        options.onShowPanel = function () {
            comboSerialNumberFunction.initData(this);
        };
        options.onHidePanel = function () {
            comboSerialNumberFunction.saveData(this);
        };

        options.onChange = function (newValue, oldValue) {
            if (valueAccessor) {
                var value = valueAccessor();
                if (value) {
                    value(newValue);
                }
            }

            if (element.exEventChange) {
                element.exEventChange(newValue, oldValue);
            }

            comboClear.showClearButton(newValue);
        };
    },
    update: function (element, valueAccessor) {
        if (valueAccessor) {
            var value = valueAccessor();
            var val = ko.utils.unwrapObservable(value);
            var text = '';

            if (!val || val.length <= 0) {
                val = new Array;
            }
            else if (val.length == 1) {
                text = val[0].toString();

                // 避免误把多个序列号保存为一个字符串的情况
                val = val[0].toString().split(',');
            }
            else {
                if (val.join) {
                    text = val.join(',');
                }
            }

            // 解决初始化时无法显示序列号的问题
            $(element).combo('setText', text);
            $(element).combo('setValues', val);
        }
    }
};